# -*- coding: utf-8 -*-
"""
压缩格式转换器
支持 ZIP、RAR 等压缩格式的互转
"""

import os
import zipfile
import shutil
from pathlib import Path


class ArchiveConverter:
    """压缩格式转换器类"""

    def __init__(self):
        pass

    def convert(self, input_path, output_dir, conversion_type):
        """
        转换压缩文件
        :param input_path: 输入文件路径
        :param output_dir: 输出目录
        :param conversion_type: 转换类型
        :return: 输出文件路径
        """
        if conversion_type == 'zip_to_rar':
            return self.zip_to_rar(input_path, output_dir)
        elif conversion_type == 'rar_to_zip':
            return self.rar_to_zip(input_path, output_dir)
        else:
            raise ValueError(f"不支持的转换类型: {conversion_type}")

    def zip_to_rar(self, zip_path, output_dir):
        """
        ZIP转RAR
        :param zip_path: ZIP文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        if not os.path.exists(zip_path):
            raise FileNotFoundError(f"文件不存在: {zip_path}")

        if not zip_path.lower().endswith('.zip'):
            raise ValueError(f"不是ZIP文件: {zip_path}")

        base_name = os.path.splitext(os.path.basename(zip_path))[0]
        output_path = os.path.join(output_dir, f"{base_name}.rar")

        print(f"\n开始转换: {os.path.basename(zip_path)}")
        print("=" * 60)

        # 创建临时解压目录
        temp_dir = os.path.join(output_dir, f"_temp_{base_name}")
        os.makedirs(temp_dir, exist_ok=True)

        try:
            # 解压ZIP文件
            print("步骤1: 解压ZIP文件...")
            with zipfile.ZipFile(zip_path, 'r') as zip_ref:
                zip_ref.extractall(temp_dir)
            print("✓ ZIP解压成功")

            # 压缩为RAR（尝试多种方法）
            print("\n步骤2: 压缩为RAR...")

            # 方法1: 使用rarfile + unrar
            try:
                import subprocess

                # 尝试使用WinRAR命令行
                winrar_paths = [
                    r'C:\Program Files\WinRAR\WinRAR.exe',
                    r'C:\Program Files (x86)\WinRAR\WinRAR.exe',
                    r'C:\Program Files\WinRAR\Rar.exe',
                    r'C:\Program Files (x86)\WinRAR\Rar.exe',
                    'rar'
                ]

                for winrar_path in winrar_paths:
                    try:
                        # 构建WinRAR命令
                        cmd = [
                            winrar_path,
                            'a',  # 添加到压缩文件
                            '-r',  # 递归子目录
                            '-ep1',  # 从名称中排除基本文件夹
                            output_path,
                            os.path.join(temp_dir, '*')
                        ]

                        result = subprocess.run(
                            cmd,
                            capture_output=True,
                            timeout=300,
                            cwd=temp_dir
                        )

                        if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                            print("✓ WinRAR压缩成功")
                            return output_path

                    except FileNotFoundError:
                        continue
                    except Exception as e:
                        print(f"  尝试 {os.path.basename(winrar_path)} 失败: {str(e)}")
                        continue

                print("✗ WinRAR未安装或不可用")

            except Exception as e:
                print(f"✗ WinRAR方法失败: {str(e)}")

            # 所有方法都失败
            print("\n" + "=" * 60)
            print("✗ ZIP转RAR失败")
            print("\n说明：")
            print("RAR是专有格式，需要安装WinRAR软件")
            print("\n建议：")
            print("1. 安装 WinRAR: https://www.rarlab.com/")
            print("2. 确保WinRAR已添加到系统PATH")
            print("3. 或手动使用WinRAR软件转换")
            print("=" * 60)

            raise Exception("ZIP转RAR失败：需要安装WinRAR")

        finally:
            # 清理临时目录
            try:
                shutil.rmtree(temp_dir)
            except:
                pass

    def rar_to_zip(self, rar_path, output_dir):
        """
        RAR转ZIP
        :param rar_path: RAR文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        if not os.path.exists(rar_path):
            raise FileNotFoundError(f"文件不存在: {rar_path}")

        if not rar_path.lower().endswith('.rar'):
            raise ValueError(f"不是RAR文件: {rar_path}")

        base_name = os.path.splitext(os.path.basename(rar_path))[0]
        output_path = os.path.join(output_dir, f"{base_name}.zip")

        print(f"\n开始转换: {os.path.basename(rar_path)}")
        print("=" * 60)

        # 创建临时解压目录
        temp_dir = os.path.join(output_dir, f"_temp_{base_name}")
        os.makedirs(temp_dir, exist_ok=True)

        try:
            # 解压RAR文件
            print("步骤1: 解压RAR文件...")

            # 方法1: 使用rarfile库
            try:
                import rarfile

                # 设置unrar工具路径
                rarfile.UNRAR_TOOL = self._find_unrar_tool()

                with rarfile.RarFile(rar_path, 'r') as rar_ref:
                    rar_ref.extractall(temp_dir)

                print("✓ RAR解压成功（使用rarfile）")

            except ImportError:
                print("✗ rarfile库未安装，尝试命令行工具...")

                # 方法2: 使用命令行工具
                import subprocess

                unrar_paths = [
                    r'C:\Program Files\WinRAR\UnRAR.exe',
                    r'C:\Program Files (x86)\WinRAR\UnRAR.exe',
                    r'C:\Program Files\WinRAR\WinRAR.exe',
                    'unrar'
                ]

                success = False
                for unrar_path in unrar_paths:
                    try:
                        result = subprocess.run(
                            [unrar_path, 'x', '-y', rar_path, temp_dir],
                            capture_output=True,
                            timeout=300
                        )

                        # 检查是否有文件被解压
                        if os.listdir(temp_dir):
                            print(f"✓ RAR解压成功（使用 {os.path.basename(unrar_path)}）")
                            success = True
                            break

                    except FileNotFoundError:
                        continue
                    except Exception as e:
                        continue

                if not success:
                    raise Exception("UnRAR工具不可用")

            # 压缩为ZIP
            print("\n步骤2: 压缩为ZIP...")
            with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zip_ref:
                # 遍历临时目录中的所有文件
                for root, dirs, files in os.walk(temp_dir):
                    for file in files:
                        file_path = os.path.join(root, file)
                        arcname = os.path.relpath(file_path, temp_dir)
                        zip_ref.write(file_path, arcname)

            print("✓ ZIP压缩成功")

            if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                print("\n✓ RAR转ZIP成功")
                return output_path
            else:
                raise Exception("输出文件未生成或为空")

        except Exception as e:
            print(f"\n✗ 转换失败: {str(e)}")

            print("\n" + "=" * 60)
            print("建议：")
            print("1. 安装rarfile库: pip install rarfile")
            print("2. 安装UnRAR工具:")
            print("   - Windows: 安装 WinRAR (https://www.rarlab.com/)")
            print("   - Linux: sudo apt-get install unrar")
            print("3. 或手动使用WinRAR软件转换")
            print("=" * 60)

            raise Exception(f"RAR转ZIP失败: {str(e)}")

        finally:
            # 清理临时目录
            try:
                shutil.rmtree(temp_dir)
            except:
                pass

    def _find_unrar_tool(self):
        """
        查找UnRAR工具路径
        :return: UnRAR工具路径
        """
        possible_paths = [
            r'C:\Program Files\WinRAR\UnRAR.exe',
            r'C:\Program Files (x86)\WinRAR\UnRAR.exe',
            '/usr/bin/unrar',
            '/usr/local/bin/unrar',
            'unrar'
        ]

        for path in possible_paths:
            if os.path.exists(path):
                return path

        # 如果都找不到，返回默认值
        return 'unrar'
